const https = require("https");
const fs = require("fs");
const path = require("path");

let privateKey = fs.readFileSync(__dirname + "/cert/key.key", "utf8");
let certificate = fs.readFileSync(__dirname + "/cert/cert.crt", "utf8");
let credentials = { key: privateKey, cert: certificate };
let ssl = 2888;
let ws;

Date.prototype.Format = function(fmt) {
    //author: meizz
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        S: this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt))
        fmt = fmt.replace(
            RegExp.$1,
            (this.getFullYear() + "").substr(4 - RegExp.$1.length)
        );
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt))
            fmt = fmt.replace(
                RegExp.$1,
                RegExp.$1.length == 1
                    ? o[k]
                    : ("00" + o[k]).substr(("" + o[k]).length)
            );
    return fmt;
};

global.uploadImage = "";
global.uploadVoice = "";

const token = require(__dirname + "/chat-server/model/token");
const chatRouter = require(__dirname + "/chat-server/routes/chat");
const uploads = require(__dirname + "/chat-server/model/multer");

let createHttpsServer = app => {
    httpsServer = https.createServer(credentials, app);
    httpsServer.listen(ssl);
    console.log("server started at https://localhost:" + ssl);
};

let makeTokenMap = () => {
    global.tokenMap = new Map();
};

let getClientIp = function(req) {
    let tmp =
        req.headers["x-forwarded-for"] ||
        req.connection.remoteAddress ||
        req.socket.remoteAddress ||
        req.connection.socket.remoteAddress ||
        "";
    let sec = tmp.match(/\d+.\d+.\d+.\d+/);
    return sec ? sec.join(".") : null;
};

let checkToken = app => {
    app.post("*", (req, res, next) => {
        if (
            req.url.indexOf("/login") === -1 &&
            req.url.indexOf("/user/add") === -1
        ) {
            if (
                global.tokenMap.get(req.headers.account) === req.headers.token
            ) {
                if (token.checkToken(req.headers.token)) {
                    next();
                } else {
                    res.status(666)
                        .send("请重新登录！")
                        .end();
                }
            } else {
                res.status(666)
                    .send("请重新登录！")
                    .end();
            }
        } else {
            next();
        }
    });
};

let createWsServer = app => {
    ws = require("express-ws")(app, httpsServer);
    app.ws("/chat/*", (wss, req) => {
        console.log("new is coming...");
        wss.on("message", mes => {
            let obj = JSON.parse(mes);
            if (
                global.tokenMap.get(obj.account) === obj.token &&
                token.checkToken(obj.token)
            ) {
                // wsCorrect = true;
                let room = req.url.split(path.sep);
                wss.room = room[2];
            } else {
                // wsCorrect = false;
            }
        });
    });
};

let connectWithWs = app => {
    let service = require(__dirname + "/chat-server/model/chat");
    app.post("/chat/send", (req, res) => {
        service.add(
            req.body.inner,
            req.body.isImg,
            req.body.isVoice,
            req.body.userId,
            req.body.roomId,
            data => {
                res.send(data)
                    .status(200)
                    .end();
                ws.getWss().clients.forEach(client => {
                    if (client.room === req.body.roomId)
                        client.send(JSON.stringify(data));
                });
            }
        );
    });

    app.post("/upload/img", uploads.any(), (req, res) => {
        res.send(req.headers.origin + "/file/img/" + global.uploadImage)
            .status(200)
            .end();
    });

    app.post("/upload/voice", uploads.any(), (req, res) => {
        res.send(
            req.headers.origin +
                "/file/voice/" +
                req.headers.account +
                "/" +
                global.uploadVoice
        )
            .status(200)
            .end();
    });
};

module.exports = {
    httpsServer: createHttpsServer,
    wsServer: createWsServer,
    connectWithWs: connectWithWs,
    makeTokenMap: makeTokenMap,
    checkToken: checkToken
};
